]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
layout: Construct the primary monitors's hot corner, too
authorJasper St. Pierre <jstpierre@mecheye.net>
Fri, 1 Mar 2013 21:00:37 +0000 (16:00 -0500)
committerJasper St. Pierre <jstpierre@mecheye.net>
Mon, 4 Mar 2013 20:50:45 +0000 (15:50 -0500)
This cleans up the code considerably, and makes it so that
one path creates all hot corners for all monitors. Why this
wasn't done originally, I have no clue...

The one complication is debouncing if the button and hot corner
are triggered in rapid succession, so we just move this tracking
to the overview.

https://bugzilla.gnome.org/show_bug.cgi?id=663661

js/ui/layout.js
js/ui/main.js
js/ui/messageTray.js
js/ui/overview.js
js/ui/panel.js

index 7fa982a3d9120f58700086a05266c3f783f85995..21f5ffd4f91c0e8af10428c8f993a4524d4c37ca 100644 (file)
@@ -18,7 +18,6 @@ const Main = imports.ui.main;
 const Params = imports.misc.params;
 const Tweener = imports.ui.tweener;
 
-const HOT_CORNER_ACTIVATION_TIMEOUT = 0.5;
 const STARTUP_ANIMATION_TIME = 0.5;
 const KEYBOARD_ANIMATION_TIME = 0.15;
 const BACKGROUND_FADE_ANIMATION_TIME = 1.0;
@@ -130,8 +129,9 @@ const LayoutManager = new Lang.Class({
         this.monitors = [];
         this.primaryMonitor = null;
         this.primaryIndex = -1;
+        this.hotCorners = [];
+
         this._keyboardIndex = -1;
-        this._hotCorners = [];
         this._leftPanelBarrier = null;
         this._rightPanelBarrier = null;
         this._trayBarrier = null;
@@ -276,56 +276,57 @@ const LayoutManager = new Lang.Class({
 
     _updateHotCorners: function() {
         // destroy old hot corners
-        for (let i = 0; i < this._hotCorners.length; i++)
-            this._hotCorners[i].destroy();
-        this._hotCorners = [];
+        for (let i = 0; i < this.hotCorners.length; i++)
+            this.hotCorners[i].destroy();
+        this.hotCorners = [];
 
         // build new hot corners
         for (let i = 0; i < this.monitors.length; i++) {
-            if (i == this.primaryIndex)
-                continue;
-
             let monitor = this.monitors[i];
             let cornerX = this._rtl ? monitor.x + monitor.width : monitor.x;
             let cornerY = monitor.y;
 
-            let haveTopLeftCorner = true;
+            if (i != this.primaryIndex) {
+                let haveTopLeftCorner = true;
 
-            // Check if we have a top left (right for RTL) corner.
-            // I.e. if there is no monitor directly above or to the left(right)
-            let besideX = this._rtl ? monitor.x + 1 : cornerX - 1;
-            let besideY = cornerY;
-            let aboveX = cornerX;
-            let aboveY = cornerY - 1;
+                // Check if we have a top left (right for RTL) corner.
+                // I.e. if there is no monitor directly above or to the left(right)
+                let besideX = this._rtl ? monitor.x + 1 : cornerX - 1;
+                let besideY = cornerY;
+                let aboveX = cornerX;
+                let aboveY = cornerY - 1;
 
-            for (let j = 0; j < this.monitors.length; j++) {
-                if (i == j)
-                    continue;
-                let otherMonitor = this.monitors[j];
-                if (besideX >= otherMonitor.x &&
-                    besideX < otherMonitor.x + otherMonitor.width &&
-                    besideY >= otherMonitor.y &&
-                    besideY < otherMonitor.y + otherMonitor.height) {
-                    haveTopLeftCorner = false;
-                    break;
-                }
-                if (aboveX >= otherMonitor.x &&
-                    aboveX < otherMonitor.x + otherMonitor.width &&
-                    aboveY >= otherMonitor.y &&
-                    aboveY < otherMonitor.y + otherMonitor.height) {
-                    haveTopLeftCorner = false;
-                    break;
+                for (let j = 0; j < this.monitors.length; j++) {
+                    if (i == j)
+                        continue;
+                    let otherMonitor = this.monitors[j];
+                    if (besideX >= otherMonitor.x &&
+                        besideX < otherMonitor.x + otherMonitor.width &&
+                        besideY >= otherMonitor.y &&
+                        besideY < otherMonitor.y + otherMonitor.height) {
+                        haveTopLeftCorner = false;
+                        break;
+                    }
+                    if (aboveX >= otherMonitor.x &&
+                        aboveX < otherMonitor.x + otherMonitor.width &&
+                        aboveY >= otherMonitor.y &&
+                        aboveY < otherMonitor.y + otherMonitor.height) {
+                        haveTopLeftCorner = false;
+                        break;
+                    }
                 }
-            }
 
-            if (!haveTopLeftCorner)
-                continue;
+                if (!haveTopLeftCorner)
+                    continue;
+            }
 
             let corner = new HotCorner(this);
-            this._hotCorners.push(corner);
+            this.hotCorners.push(corner);
             corner.actor.set_position(cornerX, cornerY);
             this.addChrome(corner.actor);
         }
+
+        this.emit('hot-corners-changed');
     },
 
     _createBackground: function(monitorIndex) {
@@ -395,7 +396,6 @@ const LayoutManager = new Lang.Class({
     },
 
     _panelBoxChanged: function() {
-        this.emit('panel-box-changed');
         this._updatePanelBarriers();
     },
 
@@ -650,8 +650,6 @@ const LayoutManager = new Lang.Class({
         if (!Main.sessionMode.isGreeter)
             this._createSecondaryBackgrounds();
 
-        this.emit('panel-box-changed');
-
         this._queueUpdateRegions();
 
         this.emit('startup-complete');
@@ -1133,24 +1131,11 @@ const HotCorner = new Lang.Class({
             this._corner.set_position(0, 0);
         }
 
-        this._activationTime = 0;
-
         this.actor.connect('leave-event',
                            Lang.bind(this, this._onEnvironsLeft));
 
-        // Clicking on the hot corner environs should result in the
-        // same behavior as clicking on the hot corner.
-        this.actor.connect('button-release-event',
-                           Lang.bind(this, this._onCornerClicked));
-
-        // In addition to being triggered by the mouse enter event,
-        // the hot corner can be triggered by clicking on it. This is
-        // useful if the user wants to undo the effect of triggering
-        // the hot corner once in the hot corner.
         this._corner.connect('enter-event',
                              Lang.bind(this, this._onCornerEntered));
-        this._corner.connect('button-release-event',
-                             Lang.bind(this, this._onCornerClicked));
         this._corner.connect('leave-event',
                              Lang.bind(this, this._onCornerLeft));
 
@@ -1225,9 +1210,7 @@ const HotCorner = new Lang.Class({
     _onCornerEntered : function() {
         if (!this._entered) {
             this._entered = true;
-            if (!Main.overview.animationInProgress) {
-                this._activationTime = Date.now() / 1000;
-
+            if (Main.overview.shouldToggleByCornerOrButton()) {
                 this.rippleAnimation();
                 Main.overview.toggle();
             }
@@ -1235,12 +1218,6 @@ const HotCorner = new Lang.Class({
         return false;
     },
 
-    _onCornerClicked : function() {
-        if (this.shouldToggleOverviewOnClick())
-            Main.overview.toggle();
-        return true;
-    },
-
     _onCornerLeft : function(actor, event) {
         if (event.get_related() != this.actor)
             this._entered = false;
@@ -1252,20 +1229,6 @@ const HotCorner = new Lang.Class({
         if (event.get_related() != this._corner)
             this._entered = false;
         return false;
-    },
-
-    // Checks if the Activities button is currently sensitive to
-    // clicks. The first call to this function within the
-    // HOT_CORNER_ACTIVATION_TIMEOUT time of the hot corner being
-    // triggered will return false. This avoids opening and closing
-    // the overview if the user both triggered the hot corner and
-    // clicked the Activities button.
-    shouldToggleOverviewOnClick: function() {
-        if (Main.overview.animationInProgress)
-            return false;
-        if (this._activationTime == 0 || Date.now() / 1000 - this._activationTime > HOT_CORNER_ACTIVATION_TIMEOUT)
-            return true;
-        return false;
     }
 });
 
index 4025bd7873e2ecf84ef621e43c268e90af6cd3f0..e0c2dd74ebb1387015aaef9113a94f116c3fd1bf 100644 (file)
@@ -148,8 +148,6 @@ function startSession() {
     else
         screenShield = new ScreenShield.ScreenShieldFallback();
 
-    // The message tray relies on being constructed
-    // after the panel.
     panel = new Panel.Panel();
     messageTray = new MessageTray.MessageTray();
     keyboard = new Keyboard.Keyboard();
index 2df4abc488fc1340d47e40c5cdb9524ebf0ad384..15629f5a53e149f53f206a03c413bda0915cbf68 100644 (file)
@@ -1672,14 +1672,13 @@ const MessageTray = new Lang.Class({
         Main.layoutManager.trackChrome(this._closeButton);
 
         Main.layoutManager.connect('primary-fullscreen-changed', Lang.bind(this, this._onFullscreenChanged));
+        Main.layoutManager.connect('hot-corners-changed', Lang.bind(this, this._hotCornersChanged));
 
         // If the overview shows or hides while we're in
         // the message tray, revert back to normal mode.
         Main.overview.connect('showing', Lang.bind(this, this._escapeTray));
         Main.overview.connect('hiding', Lang.bind(this, this._escapeTray));
 
-        // Track if we've added the activities button
-        this._activitiesButtonAdded = false;
         Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
 
         Main.wm.addKeybinding('toggle-message-tray',
@@ -1703,6 +1702,7 @@ const MessageTray = new Lang.Class({
         this._trayDwellTimeoutId = 0;
         this._setupTrayDwellIfNeeded();
         this._sessionUpdated();
+        this._hotCornersChanged();
 
         this._noMessages = new St.Label({ text: _("No Messages"),
                                           style_class: 'no-messages-label',
@@ -1775,11 +1775,6 @@ const MessageTray = new Lang.Class({
     },
 
     _sessionUpdated: function() {
-        if (!this._activitiesButtonAdded && Main.panel.statusArea.activities) {
-            this._activitiesButtonAdded = true;
-            this._grabHelper.addActor(Main.panel.statusArea.activities.hotCorner.actor);
-        }
-
         if ((Main.sessionMode.isLocked || Main.sessionMode.isGreeter) && this._inCtrlAltTab) {
             Main.ctrlAltTabManager.removeGroup(this._summary);
             this._inCtrlAltTab = false;
@@ -2101,6 +2096,13 @@ const MessageTray = new Lang.Class({
         this._updateState();
     },
 
+    _hotCornersChanged: function() {
+        let primary = Main.layoutManager.primaryIndex;
+        let corner = Main.layoutManager.hotCorners[primary];
+        if (corner && corner.actor)
+            this._grabHelper.addActor(corner.actor);
+    },
+
     _onTrayHoverChanged: function() {
         if (this.actor.hover) {
             // No dwell inside notifications at the bottom of the screen
index 6f236081deed5b45c8d23191f1a7a943b8c736d1..35eb020291101d2e11a312324e8248d140a276a5 100644 (file)
@@ -33,6 +33,8 @@ const SHADE_ANIMATION_TIME = .20;
 
 const DND_WINDOW_SWITCH_TIMEOUT = 1250;
 
+const OVERVIEW_ACTIVATION_TIMEOUT = 0.5;
+
 const ShellInfo = new Lang.Class({
     Name: 'ShellInfo',
 
@@ -146,6 +148,8 @@ const Overview = new Lang.Class({
         this._backgroundGroup.hide();
         this._bgManagers = [];
 
+        this._activationTime = 0;
+
         this.visible = false;           // animating to overview, in overview, animating out
         this._shown = false;            // show() and not hide()
         this._shownTemporarily = false; // showTemporarily() and not hideTemporarily()
@@ -536,6 +540,7 @@ const Overview = new Lang.Class({
         this.visible = true;
         this.animationInProgress = true;
         this.visibleTarget = true;
+        this._activationTime = Date.now() / 1000;
 
         // All the the actors in the window group are completely obscured,
         // hiding the group holding them while the Overview is displayed greatly
@@ -633,6 +638,20 @@ const Overview = new Lang.Class({
             this.show();
     },
 
+    // Checks if the Activities button is currently sensitive to
+    // clicks. The first call to this function within the
+    // OVERVIEW_ACTIVATION_TIMEOUT time of the hot corner being
+    // triggered will return false. This avoids opening and closing
+    // the overview if the user both triggered the hot corner and
+    // clicked the Activities button.
+    shouldToggleByCornerOrButton: function() {
+        if (this.animationInProgress)
+            return false;
+        if (this._activationTime == 0 || Date.now() / 1000 - this._activationTime > OVERVIEW_ACTIVATION_TIMEOUT)
+            return true;
+        return false;
+    },
+
     //// Private methods ////
 
     _syncInputMode: function() {
index 558ce67f267530a57f0da9c87156bcb4a655c124..2b1ed9b79d938f0941a9d59cf933d176e7b4a2ea 100644 (file)
@@ -18,7 +18,6 @@ const Atk = imports.gi.Atk;
 const Config = imports.misc.config;
 const CtrlAltTab = imports.ui.ctrlAltTab;
 const DND = imports.ui.dnd;
-const Layout = imports.ui.layout;
 const Overview = imports.ui.overview;
 const PopupMenu = imports.ui.popupMenu;
 const PanelMenu = imports.ui.panelMenu;
@@ -630,23 +629,15 @@ const ActivitiesButton = new Lang.Class({
         this.parent(0.0, null, true);
         this.actor.accessible_role = Atk.Role.TOGGLE_BUTTON;
 
-        let container = new Shell.GenericContainer();
-        container.connect('get-preferred-width', Lang.bind(this, this._containerGetPreferredWidth));
-        container.connect('get-preferred-height', Lang.bind(this, this._containerGetPreferredHeight));
-        container.connect('allocate', Lang.bind(this, this._containerAllocate));
-        this.actor.add_actor(container);
         this.actor.name = 'panelActivities';
 
         /* Translators: If there is no suitable word for "Activities"
            in your language, you can use the word for "Overview". */
         this._label = new St.Label({ text: _("Activities") });
-        container.add_actor(this._label);
+        this.actor.add_actor(this._label);
 
         this.actor.label_actor = this._label;
 
-        this.hotCorner = new Layout.HotCorner(Main.layoutManager);
-        container.add_actor(this.hotCorner.actor);
-
         this.actor.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
         this.actor.connect_after('button-release-event', Lang.bind(this, this._onButtonRelease));
         this.actor.connect_after('key-release-event', Lang.bind(this, this._onKeyRelease));
@@ -661,44 +652,6 @@ const ActivitiesButton = new Lang.Class({
         }));
 
         this._xdndTimeOut = 0;
-
-        // Since the hot corner uses stage coordinates, Clutter won't
-        // queue relayouts for us when the panel moves. Queue a relayout
-        // when that happens.
-        Main.layoutManager.connect('panel-box-changed', Lang.bind(this, function() {
-            container.queue_relayout();
-        }));
-    },
-
-    _containerGetPreferredWidth: function(actor, forHeight, alloc) {
-        [alloc.min_size, alloc.natural_size] = this._label.get_preferred_width(forHeight);
-    },
-
-    _containerGetPreferredHeight: function(actor, forWidth, alloc) {
-        [alloc.min_size, alloc.natural_size] = this._label.get_preferred_height(forWidth);
-    },
-
-    _containerAllocate: function(actor, box, flags) {
-        this._label.allocate(box, flags);
-
-        // The hot corner needs to be outside any padding/alignment
-        // that has been imposed on us
-        let primary = Main.layoutManager.primaryMonitor;
-        let hotBox = new Clutter.ActorBox();
-        let ok, x, y;
-        if (actor.get_text_direction() == Clutter.TextDirection.LTR) {
-            [ok, x, y] = actor.transform_stage_point(primary.x, primary.y)
-        } else {
-            [ok, x, y] = actor.transform_stage_point(primary.x + primary.width, primary.y);
-            // hotCorner.actor has northeast gravity, so we don't need
-            // to adjust x for its width
-        }
-
-        hotBox.x1 = Math.round(x);
-        hotBox.x2 = hotBox.x1 + this.hotCorner.actor.width;
-        hotBox.y1 = Math.round(y);
-        hotBox.y2 = hotBox.y1 + this.hotCorner.actor.height;
-        this.hotCorner.actor.allocate(hotBox, flags);
     },
 
     handleDragOver: function(source, actor, x, y, time) {
@@ -715,7 +668,7 @@ const ActivitiesButton = new Lang.Class({
 
     _onCapturedEvent: function(actor, event) {
         if (event.type() == Clutter.EventType.BUTTON_PRESS) {
-            if (!this.hotCorner.shouldToggleOverviewOnClick())
+            if (!Main.overview.shouldToggleByCornerOrButton())
                 return true;
         }
         return false;